home *** CD-ROM | disk | FTP | other *** search
/ Best of Shareware / Best of PC Windows Shareware 1.0 - Wayzata Technology (7111) (1993).iso / mac / DOS / TELECOMM / PCCP047 / COMSCRPT.C < prev    next >
Text File  |  1992-08-28  |  23KB  |  895 lines

  1. /*    Copyright (C) 1992 Peter Edward Cann, all rights reserved.
  2.  *    MicroSoft QuickC: >qcl term.c graphics.lib
  3.  */
  4.  
  5. #include<stdio.h>
  6. #include<bios.h>
  7. #include<dos.h>
  8. #include<fcntl.h>
  9. #include<signal.h>
  10. #include<process.h>
  11. #include"port.h"
  12.  
  13. #define PROGSIZ 512
  14.  
  15. struct line
  16.     {
  17.     char type;
  18.     union
  19.         {
  20.         unsigned char byte;
  21.         int number;
  22.         struct
  23.             {
  24.             int retries;
  25.             unsigned char label;
  26.             unsigned char reg;
  27.             }
  28.             retry;
  29.         struct
  30.             {
  31.             unsigned char label;
  32.             unsigned char string[81];
  33.             unsigned char ntokens;
  34.             }
  35.             l_and_s;
  36.         unsigned char string[81];
  37.         }
  38.         stuff;
  39.     }
  40.     program[PROGSIZ];
  41.  
  42. #define MAXNSCANS 32
  43.  
  44. struct
  45.     {
  46.     unsigned char index;
  47.     unsigned char *str;
  48.     unsigned char hitlabel;
  49.     }
  50.     scans[MAXNSCANS];
  51.  
  52. int nscans;
  53.  
  54. #define MAXKEYS 64
  55.  
  56. struct
  57.     {
  58.     unsigned char key;
  59.     unsigned char label;
  60.     }
  61.     keys[MAXKEYS];
  62.  
  63. short int labels[256]; /* Not a #define cause we use unsigned char all over */
  64.  
  65. unsigned short int rregs[256]; /* Same deal */
  66.  
  67. quit()
  68.     {
  69.     cleanup(0);
  70.     exit(99);
  71.     }
  72.  
  73. int demonflag;
  74.  
  75. sendchar(c)
  76.     unsigned char c;
  77.     {
  78.     while(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  79.         {
  80.         if(kbhit())
  81.             if(getch()==24)
  82.                 demonflag=1;
  83.         }
  84.     outp(basereg, c);
  85.     return(0);
  86.     }
  87.  
  88. int follow;
  89.  
  90. sleep()
  91.     {
  92.     long tod, tod1, day;
  93.     day=0;
  94.     _bios_timeofday(_TIME_GETCLOCK, &tod);
  95.     while(1)
  96.         {
  97.         if(_bios_timeofday(_TIME_GETCLOCK, &tod1))
  98.             day=20*60*60*24;
  99.         if((tod1+day-tod)>8)
  100.             break;
  101.         }
  102.     }
  103.  
  104. main(argc, argv)
  105.     int argc;
  106.     char **argv;
  107.     {
  108.     FILE *scriptfd;
  109.     char c, fpname[256], str[81], *strptr, spawnpath[81];
  110.     char comstr[16], speedstr[16], bitsstr[16], *spawnargv[41];
  111.     int i, j, proglen, value[8], flag, progcnt, demon, curkey, spawnargc;
  112.     long timestamp, tstamp, tstamp1, dayofticksp;
  113.     index=follow=0;
  114.     printf("Copyright (C) 1992 Peter Edward Cann, all rights reserved.\n");
  115.     if(!strcmp(getenv("REMOTE"), "YES"))
  116.         {
  117.         printf("You appear to be logged in remotely, judging by the environment\n");
  118.         printf("variable REMOTE, so it strikes me as somewhat peculiar that you\n");
  119.         printf("want to run COMSCRPT. Are you sure you want to do it? (y or n) --> ");
  120.         if(getchar()!='y') /* Note getchar() and not getch()! */
  121.             {
  122.             printf("I didn't think so!\n");
  123.             exit(99);
  124.             }
  125.         else
  126.             printf("OK, you're the boss!");
  127.         }
  128.     if(argc!=2)
  129.         {
  130.         printf("USAGE: comscrpt <script file basename>\n");
  131.         printf("The environment variable PCCPPATH is used for the script file if set.\n");
  132.         exit(1);
  133.         }
  134.     fpname[0]='\0';
  135.     if(getenv("PCCPPATH")==NULL)
  136.         sprintf(fpname, "%s.scr", argv[1]);
  137.     else
  138.         sprintf(fpname, "%s\\%s.scr", getenv("PCCPPATH"), argv[1]);
  139.     if((scriptfd=fopen(fpname, "r"))==NULL)
  140.         {
  141.         printf("Error opening script file %s.\n", fpname);
  142.         exit(2);
  143.         }
  144.     fgets(str, 80, scriptfd);
  145.     if(sscanf(str, "%s %s %s", comstr, speedstr, bitsstr)!=3)
  146.         {
  147.         printf("Can't read init params.\n");
  148.         exit(10);
  149.         }
  150.     comnum=atoi(comstr)-1;
  151.     speed=atoi(speedstr);
  152.     parity=bitsstr[1];
  153.     databits=bitsstr[0];
  154.     stopbits=bitsstr[2];
  155.     setport();
  156.     for(i=0;i<256;++i)
  157.         labels[i]=-1;
  158.     signal(SIGINT, quit);
  159.     readset();
  160.     setup();
  161.     for(i=0;i<256;++i)
  162.         rregs[i]=0;
  163.     /* Parse */
  164.     printf("Parsing...\n");
  165.     flag=0;
  166.     for(proglen=0;proglen<PROGSIZ;++proglen)
  167.         {
  168.         if(fgets(str, 80, scriptfd)==NULL)
  169.             {
  170.             flag=1;
  171.             break;
  172.             }
  173.         for(i=0;i<80;++i)
  174.             if(str[i]=='\n')
  175.                 {
  176.                 str[i]='\0';
  177.                 break;
  178.                 }
  179.             else if(str[i]=='\0')
  180.                 break;
  181.         if(!strlen(str))
  182.             proglen--;
  183.         else
  184.             {
  185.             if((str[0]!=';')&&(str[0]!='c')&&(str[0]!='+')&&(str[0]!='-')&&(str[1]!=' '))
  186.                 {
  187.                 printf("Missing first delimiting space at statement %d.\n", proglen);
  188.                 printf("Statement reads:\n%s\n", str);
  189.                 cleanup(0);
  190.                 exit(11);
  191.                 }
  192.             switch(str[0])
  193.                 {
  194.                 case ':':
  195.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  196.                         {
  197.                         printf("Bad scan of label (:) before statement %d.\n", proglen);
  198.                         cleanup(0);
  199.                         exit(11);
  200.                         }
  201.                     if((value[0]<0)||(value[0]>255))
  202.                         {
  203.                         printf("Label %d out of range.\n", value[0]);
  204.                         cleanup(0);
  205.                         exit(11);
  206.                         }
  207.                     if(labels[value[0]]!=-1)
  208.                         {
  209.                         printf("Label %d duplicated at statement %d.\n", value[0], proglen);
  210.                         cleanup(0);
  211.                         exit(11);
  212.                         }
  213.                     labels[value[0]]=proglen;
  214.                     proglen--;
  215.                     break;
  216.                 case '*':
  217.                     program[proglen].type='*';
  218.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  219.                         {
  220.                         printf("Bad scan of * at statement %d.\n", proglen);
  221.                         cleanup(0);
  222.                         exit(11);
  223.                         }
  224.                     if((value[0]<0)||(value[0]>255))
  225.                         {
  226.                         printf("Label out of range in * demon at statement %d.\n", proglen);
  227.                         printf("Statement reads:\n%s\n", str);
  228.                         cleanup(0);
  229.                         exit(11);
  230.                         }
  231.                     program[proglen].stuff.number=value[0];
  232.                     break;
  233.                 case 'g':
  234.                 case 'G':
  235.                     program[proglen].type='g';
  236.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  237.                         {
  238.                         printf("Bad scan of Goto at statement %d.\n", proglen);
  239.                         printf("Statement reads:\n%s\n", str);
  240.                         cleanup(0);
  241.                         exit(11);
  242.                         }
  243.                     if((value[0]<0)||(value[0]>255))
  244.                         {
  245.                         printf("Label out of range in Goto at statement %d.\n", proglen);
  246.                         printf("Statement reads:\n%s\n", str);
  247.                         cleanup(0);
  248.                         exit(11);
  249.                         }
  250.                     program[proglen].stuff.byte=(unsigned char)value[0];
  251.                     break;
  252.                 case 'r':
  253.                 case 'R':
  254.                     program[proglen].type='r';
  255.                     if(sscanf(str, "%*c %d %d %d", &value[0], &value[1], &value[2])!=3)
  256.                         {
  257.                         printf("Bad scan of Retry at statement %d.\n", proglen);
  258.                         printf("Statement reads:\n%s\n", str);
  259.                         cleanup(0);
  260.                         exit(11);
  261.                         }
  262.                     if((value[0]<0)||(value[0]>255))
  263.                         {
  264.                         printf("Label out of range in Retry at statement %d.\n", proglen);
  265.                         printf("Statement reads:\n%s\n", str);
  266.                         cleanup(0);
  267.                         exit(11);
  268.                         }
  269.                     if((value[2]<0)||(value[2]>255))
  270.                         {
  271.                         printf("Register out of range in Retry at statement %d.\n", proglen);
  272.                         printf("Statement reads:\n%s\n", str);
  273.                         cleanup(0);
  274.                         exit(11);
  275.                         }
  276.                     program[proglen].stuff.retry.label=value[0];
  277.                     program[proglen].stuff.retry.retries=value[1];
  278.                     program[proglen].stuff.retry.reg=value[2];
  279.                     break;
  280.                 case '0':
  281.                     program[proglen].type='0';
  282.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  283.                         {
  284.                         printf("Bad scan of Zero Retry (0) at statement %d.\n", proglen);
  285.                         printf("Statement reads:\n%s\n", str);
  286.                         cleanup(0);
  287.                         exit(11);
  288.                         }
  289.                     if((value[0]<0)||(value[0]>255))
  290.                         {
  291.                         printf("reg out of range in Zero Retry (0) at statement %d.\n", proglen);
  292.                         printf("Statement reads:\n%s\n", str);
  293.                         cleanup(0);
  294.                         exit(11);
  295.                         }
  296.                     program[proglen].stuff.byte=value[0];
  297.                     break;
  298.                 case 'p':
  299.                 case 'P':
  300.                     program[proglen].type='p';
  301.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  302.                         {
  303.                         printf("Bad scan of Process at statement %d.\n", proglen);
  304.                         printf("Statement reads:\n%s\n", str);
  305.                         cleanup(0);
  306.                         exit(11);
  307.                         }
  308.                     program[proglen].stuff.number=value[0];
  309.                     break;
  310.                 case '>':
  311.                     program[proglen].type='>';
  312.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  313.                         {
  314.                         printf("Bad scan of > at statement %d.\n", proglen);
  315.                         printf("Statement reads:\n%s\n", str);
  316.                         cleanup(0);
  317.                         exit(11);
  318.                         }
  319.                     if((value[0]<0)||(value[0]>255))
  320.                         {
  321.                         printf("Label out of range in Look-for (>) at statement %d.\n", proglen);
  322.                         printf("Statement reads:\n%s\n", str);
  323.                         cleanup(0);
  324.                         exit(11);
  325.                         }
  326.                     program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
  327.                     flag=j=0;
  328.                     for(i=2;i<80;++i)
  329.                         {
  330.                         if(flag)
  331.                             if(str[i]=='|')
  332.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  333.                             else if(str[i]=='`')
  334.                                 {
  335.                                 if(str[++i]<'A')
  336.                                     program[proglen].stuff.l_and_s.string[j]=(str[i]-'0')<<4;
  337.                                 else if(str[i]<'a')
  338.                                     program[proglen].stuff.l_and_s.string[j]=(str[i]-'A'+10)<<4;
  339.                                 else
  340.                                     program[proglen].stuff.l_and_s.string[j]=(str[i]-'a'+10)<<4;
  341.                                 if(str[++i]<'A')
  342.                                     program[proglen].stuff.l_and_s.string[j++]|=str[i]-'0';
  343.                                 else if(str[i]<'a')
  344.                                     program[proglen].stuff.l_and_s.string[j++]|=str[i]-'A'+10;
  345.                                 else
  346.                                     program[proglen].stuff.l_and_s.string[j++]|=str[i]-'a'+10;
  347.                                 }
  348.                             else
  349.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  350.                         if(str[i]==' ')
  351.                             flag=1;
  352.                         if(str[i]=='\0')
  353.                             break;
  354.                         }
  355.                     break;
  356.                 case '?':
  357.                     program[proglen].type='?';
  358.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  359.                         {
  360.                         printf("Bad scan of ? at statement %d.\n", proglen);
  361.                         printf("Statement reads:\n%s\n", str);
  362.                         cleanup(0);
  363.                         exit(11);
  364.                         }
  365.                     if((value[0]<0)||(value[0]>255))
  366.                         {
  367.                         printf("Label out of range in ? at statement %d.\n", proglen);
  368.                         printf("Statement reads:\n%s\n", str);
  369.                         cleanup(0);
  370.                         exit(11);
  371.                         }
  372.                     program[proglen].stuff.byte=value[0];
  373.                     break;
  374.                 case 'd':
  375.                 case 'D':
  376.                     program[proglen].type='d';
  377.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  378.                         {
  379.                         printf("Bad scan of d at statement %d.\n", proglen);
  380.                         printf("Statement reads:\n%s\n", str);
  381.                         cleanup(0);
  382.                         exit(11);
  383.                         }
  384.                     if((value[0]<0)||(value[0]>255))
  385.                         {
  386.                         printf("Label out of range in d at statement %d.\n", proglen);
  387.                         printf("Statement reads:\n%s\n", str);
  388.                         cleanup(0);
  389.                         exit(11);
  390.                         }
  391.                     program[proglen].stuff.byte=value[0];
  392.                     break;
  393.                 case '<':
  394.                     program[proglen].type='<';
  395.                     j=0;
  396.                     for(i=2;i<80;++i)
  397.                         {
  398.                         if(str[i]=='|')
  399.                             program[proglen].stuff.string[j++]='\r';
  400.                         else if(str[i]=='`')
  401.                             {
  402.                             if(str[++i]<'A')
  403.                                 program[proglen].stuff.string[j]=(str[i]-'0')<<4;
  404.                             else if(str[i]<'a')
  405.                                 program[proglen].stuff.string[j]=(str[i]-'A'+10)<<4;
  406.                             else
  407.                                 program[proglen].stuff.string[j]=(str[i]-'a'+10)<<4;
  408.                             if(str[++i]<'A')
  409.                                 program[proglen].stuff.string[j++]|=str[i]-'0';
  410.                             else if(str[i]<'a')
  411.                                 program[proglen].stuff.string[j++]|=str[i]-'A'+10;
  412.                             else
  413.                                 program[proglen].stuff.string[j++]|=str[i]-'a'+10;
  414.                             }
  415.                         else
  416.                             program[proglen].stuff.string[j++]=str[i];
  417.                         if(str[i]=='\0')
  418.                             break;
  419.                         }
  420.                     break;
  421.                 case '!':
  422.                     program[proglen].type='!';
  423.                     j=0;
  424.                     for(i=2;i<80;++i)
  425.                         {
  426.                         if(str[i]=='|')
  427.                             program[proglen].stuff.string[j++]='\n';
  428.                         else if(str[i]=='~')
  429.                             program[proglen].stuff.string[j++]='\007';
  430.                         else
  431.                             program[proglen].stuff.string[j++]=str[i];
  432.                         if(str[i]=='\0')
  433.                             break;
  434.                         }
  435.                     break;
  436.                 case 's':
  437.                 case 'S':
  438.                     program[proglen].type='s';
  439.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  440.                         {
  441.                         printf("Bad scan of System (s) at statement %d.\n", proglen);
  442.                         printf("Statement reads:\n%s\n", str);
  443.                         cleanup(0);
  444.                         exit(11);
  445.                         }
  446.                     if((value[0]<0)||(value[0]>255))
  447.                         {
  448.                         printf("Label out of range in System (s) at statement %d.\n", proglen);
  449.                         printf("Statement reads:\n%s\n", str);
  450.                         cleanup(0);
  451.                         exit(11);
  452.                         }
  453.                     program[proglen].stuff.l_and_s.label=value[0];
  454.                     flag=j=0;
  455.                     for(i=2;i<80;++i)
  456.                         {
  457.                         if(flag)
  458.                             if(str[i]=='|')
  459.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  460.                             else
  461.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  462.                         if(str[i]==' ')
  463.                             flag=1;
  464.                         if(str[i]=='\0')
  465.                             break;
  466.                         }
  467.                     break;
  468.                 case 'X':
  469.                 case 'x':
  470.                     program[proglen].type='x';
  471.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  472.                         {
  473.                         printf("Bad scan of Execute (x) at statement %d.\n", proglen);
  474.                         printf("Statement reads:\n%s\n", str);
  475.                         cleanup(0);
  476.                         exit(11);
  477.                         }
  478.                     if((value[0]<0)||(value[0]>255))
  479.                         {
  480.                         printf("Label out of range in Execute (x) at statement %d.\n", proglen);
  481.                         printf("Statement reads:\n%s\n", str);
  482.                         cleanup(0);
  483.                         exit(11);
  484.                         }
  485.                     program[proglen].stuff.l_and_s.label=value[0];
  486.                     flag=j=0;
  487.                     program[proglen].stuff.l_and_s.ntokens=0;
  488.                     for(i=2;i<80;++i)
  489.                         {
  490.                         if(flag)
  491.                             if(str[i]=='|')
  492.                                 program[proglen].stuff.l_and_s.string[j++]='\r';
  493.                             else if(str[i]==' ')
  494.                                 {
  495.                                 program[proglen].stuff.l_and_s.string[j++]='\0';
  496.                                 program[proglen].stuff.l_and_s.ntokens++;
  497.                                 }
  498.                             else
  499.                                 program[proglen].stuff.l_and_s.string[j++]=str[i];
  500.                         if(str[i]==' ')
  501.                             flag=1;
  502.                         if(str[i]=='\0')
  503.                             break;
  504.                         }
  505.                     program[proglen].stuff.l_and_s.string[80]='\0';
  506.                     program[proglen].stuff.l_and_s.ntokens++;
  507.                     break;
  508.                 case '+':
  509.                     program[proglen].type='+';
  510.                     break;
  511.                 case '-':
  512.                     program[proglen].type='-';
  513.                     break;
  514.                 case 'w':
  515.                 case 'W':
  516.                     program[proglen].type='w';
  517.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  518.                         {
  519.                         printf("Bad scan of Wait (w) at statement %d.\n", proglen);
  520.                         printf("Statement reads:\n%s\n", str);
  521.                         cleanup(0);
  522.                         exit(11);
  523.                         }
  524.                     program[proglen].stuff.number=value[0];
  525.                     break;
  526.                 case 'k':
  527.                 case 'K':
  528.                     program[proglen].type='k';
  529.                     if(sscanf(str, "%*c %d %c", &value[0], &c)!=2)
  530.                         {
  531.                         printf("Bad scan of Key (k) at statement %d.\n", proglen);
  532.                         printf("Statement reads:\n%s\n", str);
  533.                         cleanup(0);
  534.                         exit(11);
  535.                         }
  536.                     if((value[0]<0)||(value[0]>255))
  537.                         {
  538.                         printf("Label out of range in Key at statement %d.\n", proglen);
  539.                         printf("Statement reads:\n%s\n", str);
  540.                         cleanup(0);
  541.                         exit(11);
  542.                         }
  543.                     program[proglen].stuff.l_and_s.label=(unsigned char)value[0];
  544.                     if(c=='|')
  545.                         program[proglen].stuff.l_and_s.string[0]='\r';
  546.                     else if(c=='`')
  547.                         {
  548.                         if(sscanf(str, "%*c %*d %*c%x", &value[0])!=1)
  549.                             {
  550.                             printf("Error scanning hex charcode in statement %d. Statement reads:\n%s\n", proglen, str);
  551.                             }
  552.                         program[proglen].stuff.l_and_s.string[0]=(unsigned char)value[0];
  553.                         }
  554.                     else
  555.                         program[proglen].stuff.l_and_s.string[0]=(unsigned char)c;
  556.                     break;
  557.                 case 'c':
  558.                 case 'C':
  559.                     program[proglen].type='c';
  560.                 case 'q':
  561.                 case 'Q':
  562.                     program[proglen].type='q';
  563.                     if(sscanf(str, "%*c %d", &value[0])!=1)
  564.                         {
  565.                         printf("Bad scan of Quit at statement %d.\n", proglen);
  566.                         printf("Statement reads:\n%s\n", str);
  567.                         cleanup(0);
  568.                         exit(11);
  569.                         }
  570.                     if((value[0]<128)&&(value[0]!=0))
  571.                         {
  572.                         printf("Quit with reserved exit code (!=0&&<128) at statement %d.\n", proglen);
  573.                         cleanup(0);
  574.                         exit(11);
  575.                         }
  576.                     program[proglen].stuff.number=value[0];
  577.                     break;
  578.                 case ';':
  579.                     proglen--;
  580.                     break;
  581.                 default:
  582.                     printf("Bad command character %c at statement %d.\n", str[0], proglen);
  583.                     printf("Statement reads:\n%s\n", str);
  584.                     cleanup(0);
  585.                     exit(10);
  586.                 }
  587.             }
  588.         }
  589.     if(!flag)
  590.         {
  591.         printf("Program too long.\n");
  592.         cleanup(0);
  593.         exit(11);
  594.         }
  595.     /* Check labels */
  596.     printf("Checking branch label validity...\n");
  597.     for(i=0;i<proglen;i++)
  598.         switch(program[i].type)
  599.             {
  600.             case 'g':
  601.             case '?':
  602.             case 'd':
  603.                 if(labels[program[i].stuff.byte]==-1)
  604.                     {
  605.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.byte, i, program[i].type);
  606.                     cleanup(0);
  607.                     exit(13);
  608.                     }
  609.                 break;
  610.             case '*':
  611.                 if((program[i].stuff.number>=0)&&(labels[program[i].stuff.number]==-1))
  612.                     {
  613.                     printf("Unlisted label %d at statement %d (*).\n", program[i].stuff.number, i);
  614.                     cleanup(0);
  615.                     exit(13);
  616.                     }
  617.                 break;
  618.             case 'r':
  619.                 if(labels[program[i].stuff.retry.label]==-1)
  620.                     {
  621.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.retry.label, i, program[i].type);
  622.                     cleanup(0);
  623.                     exit(13);
  624.                     }
  625.                 break;
  626.             case '>':
  627.             case 'k':
  628.                 if(labels[program[i].stuff.l_and_s.label]==-1)
  629.                     {
  630.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
  631.                     cleanup(0);
  632.                     exit(13);
  633.                     }
  634.                 break;
  635.             case 'x':
  636.             case 's':
  637.                 if(labels[program[i].stuff.l_and_s.label]==-1)
  638.                     {
  639.                     printf("Unlisted label %d at statement %d (%c).\n", program[i].stuff.l_and_s.label, i, program[i].type);
  640.                     cleanup(0);
  641.                     exit(13);
  642.                     }
  643.                 break;
  644.             }
  645.     printf("Executing...\n");
  646.     /* Execute */
  647.     progcnt=nscans=curkey=0;
  648.     demonflag=0;
  649.     demon=-1;
  650.     while(1)
  651.         {
  652.         if(kbhit())
  653.             if(getch()==24)
  654.                 if(demon>=0)
  655.                     progcnt=demon;
  656.         if(demonflag)
  657.             {
  658.             demonflag=0;
  659.             if(demon>=0)
  660.                 progcnt=demon;
  661.             }
  662.         if(progcnt>=proglen)
  663.             {
  664.             printf("\nFell through end of program.\n");
  665.             cleanup(0);
  666.             exit(100);
  667.             }
  668.         switch(program[progcnt].type)
  669.             {
  670.             case 'g':
  671.                 progcnt=labels[program[progcnt].stuff.byte];
  672.                 break;
  673.             case '*':
  674.                 if(program[progcnt].stuff.number>=0)
  675.                     demon=labels[program[progcnt].stuff.number];
  676.                 else
  677.                     demon=-1;
  678.                 progcnt++;
  679.                 break;
  680.             case 'r':
  681.                 if(++rregs[program[progcnt].stuff.retry.reg]>=program[progcnt].stuff.retry.retries)
  682.                     {
  683.                     rregs[program[progcnt].stuff.retry.reg]=0;
  684.                     progcnt=labels[program[progcnt].stuff.retry.label];
  685.                     }
  686.                 else
  687.                     progcnt++;
  688.                 break;
  689.             case '0':
  690.                 rregs[program[progcnt].stuff.byte]=0;
  691.                 progcnt++;
  692.                 break;
  693.             case 'p':
  694.                 timestamp=time(NULL);
  695.                 flag=1;
  696.                 while(flag)
  697.                     {
  698.                     while(1)
  699.                         {
  700.                         if(program[progcnt].stuff.number&&((time(NULL)-timestamp)>program[progcnt].stuff.number))
  701.                             {
  702.                             progcnt++;
  703.                             flag=0;
  704.                             break;
  705.                             }
  706.                         if(follow!=index)
  707.                             {
  708.                             putch(c=buf[follow++]);
  709.                             follow%=TBUFSIZ;
  710.                             if((c&0x7f)!='\n')
  711.                                 break;
  712.                             }
  713.                         if(kbhit())
  714.                             if(getch()==24)
  715.                                 {
  716.                                 demonflag=1;
  717.                                 flag=0;
  718.                                 break;
  719.                                 }
  720.                         }
  721.                     if(!flag)
  722.                         break;
  723.                     for(i=0;i<nscans;++i)
  724.                         if((scans[i].str[scans[i].index]&0x7f)==(c&0x7f))
  725.                             if(scans[i].str[++scans[i].index]=='\0')
  726.                                 {
  727.                                 if(labels[scans[i].hitlabel]==-1)
  728.                                     {
  729.                                     printf("\nGoto unlisted label %d at statement %d.\n", scans[i].hitlabel, progcnt);
  730.                                     cleanup(0);
  731.                                     exit(12);
  732.                                     }
  733.                                 progcnt=labels[scans[i].hitlabel];
  734.                                 flag=0;
  735.                                 break;
  736.                                 }
  737.                             else;
  738.                         else
  739.                             scans[i].index=0;
  740.                     }
  741.                 nscans=0;
  742.                 break;
  743.             case '>':
  744.                 if(nscans>=MAXNSCANS)
  745.                     {
  746.                     printf("Too many lookfors (>).\n");
  747.                     progcnt++;
  748.                     break;
  749.                     }
  750.                 scans[nscans].index=0;
  751.                 scans[nscans].str=program[progcnt].stuff.l_and_s.string;
  752.                 scans[nscans++].hitlabel=program[progcnt].stuff.l_and_s.label;
  753.                 progcnt++;
  754.                 break;
  755.             case '?':
  756.                 if(!((inp(basereg+STATREG)&TXMTMASK)&&(inp(basereg+MSTATREG)&CTSMASK)))
  757.                     progcnt=labels[program[progcnt].stuff.byte];
  758.                 else
  759.                     progcnt++;
  760.                 break;
  761.             case 'd':
  762.                 if(inp(basereg+MSTATREG)&DCDMASK)
  763.                     progcnt=labels[program[progcnt].stuff.byte];
  764.                 else
  765.                     progcnt++;
  766.                 break;
  767.             case '<':
  768.                 for(i=0;i<80;i++)
  769.                     if(program[progcnt].stuff.string[i]=='\0')
  770.                         break;
  771.                     else if(program[progcnt].stuff.string[i]=='~')
  772.                         sleep();
  773.                     else if(program[progcnt].stuff.string[i]=='^')
  774.                         {
  775.                         _bios_timeofday(_TIME_GETCLOCK, &tstamp);
  776.                         outp(basereg+LCTLREG, lctl|0x40);
  777.                         dayofticksp=0;
  778.                         while(1)
  779.                             {
  780.                             if(_bios_timeofday(_TIME_GETCLOCK, &tstamp1))
  781.                                 dayofticksp+=20*60*60*24;
  782.                             if(tstamp1+dayofticksp-tstamp>10)
  783.                                 break;
  784.                             }
  785.                         outp(basereg+LCTLREG, lctl);
  786.                         }
  787.                     else
  788.                         sendchar(program[progcnt].stuff.string[i]);
  789.                 progcnt++;
  790.                 break;
  791.             case '!':
  792.                 printf("%s", program[progcnt].stuff.string);
  793.                 progcnt++;
  794.                 break;
  795.             case 's':
  796.                 printf("\n");
  797.                 cleanup(INHCTL);
  798.                 if(system(program[progcnt].stuff.l_and_s.string)==-1)
  799.                     {
  800.                     progcnt=labels[program[progcnt].stuff.l_and_s.label];
  801.                     }
  802.                 else
  803.                     progcnt++;
  804.                 setup();
  805.                 printf("\nBack to script.\n");
  806.                 break;
  807.             case 'x':
  808.                 printf("\n");
  809.                 cleanup(INHCTL);
  810.                 spawnargc=0;
  811.                 if(program[progcnt].stuff.l_and_s.string[0]!='\0')
  812.                     {
  813.                     spawnargv[spawnargc++]=&program[progcnt].stuff.l_and_s.string[0];
  814.                     for(j=0,i=1;i<program[progcnt].stuff.l_and_s.ntokens;i++)
  815.                         {
  816.                         while(program[progcnt].stuff.l_and_s.string[j++]!='\0');
  817.                         spawnargv[spawnargc++]=&program[progcnt].stuff.l_and_s.string[j];
  818.                         }
  819.                     spawnargv[spawnargc++]=NULL;
  820.                     strcpy(spawnpath, spawnargv[0]);
  821.                     if(value[0]=spawnvp(P_WAIT, spawnpath, spawnargv))
  822.                         {
  823.                         progcnt=labels[program[progcnt].stuff.l_and_s.label];
  824.                         }
  825.                     else
  826.                         progcnt++;
  827.                     }
  828.                 else
  829.                     progcnt++;
  830.                 setup();
  831.                 printf("\nExit code = %d.  Back to script.\n", value[0]);
  832.                 break;
  833.             case '+':
  834.                 outp(basereg+MCTLREG, 0x0b);
  835.                 progcnt++;
  836.                 break;
  837.             case '-':
  838.                 outp(basereg+MCTLREG, 0x0a);
  839.                 progcnt++;
  840.                 break;
  841.             case 'k':
  842.                 if(curkey>=MAXKEYS)
  843.                     {
  844.                     printf("Excess key daemon ignored.\n");
  845.                     progcnt++;
  846.                     break;
  847.                     }
  848.                 keys[curkey].key=program[progcnt].stuff.l_and_s.string[0];
  849.                 keys[curkey++].label=program[progcnt].stuff.l_and_s.label;
  850.                 progcnt++;
  851.                 break;
  852.             case 'w':
  853.                 timestamp=time(NULL);
  854.                 while(1)
  855.                     {
  856.                     if(program[progcnt].stuff.number&&((time(NULL)-timestamp)>program[progcnt].stuff.number))
  857.                         {
  858.                         printf("\nKeyboard entry timeout.\n");
  859.                         progcnt++;
  860.                         break;
  861.                         }
  862.                     if(kbhit())
  863.                         {
  864.                         c=getch();
  865.                         if(c==24)
  866.                             if(demon>=0)
  867.                                 {
  868.                                 progcnt=demon;
  869.                                 break;
  870.                                 }
  871.                         for(i=0;i<curkey;i++)
  872.                             if(c==keys[i].key)
  873.                                 {
  874.                                 progcnt=labels[keys[i].label];
  875.                                 break;
  876.                                 }
  877.                         if(i>=curkey)
  878.                             printf("\n\007Non-programmed key! (%c) Re-enter: -->", c);
  879.                         else
  880.                             break;
  881.                         }
  882.                     }
  883.                 curkey=0;
  884.                 break;
  885.             case 'c':
  886.                 curkey=nscans=0;
  887.                 progcnt++;
  888.                 break;
  889.             case 'q':
  890.                 cleanup(0);
  891.                 exit(program[progcnt].stuff.number);
  892.             }
  893.         }
  894.     }
  895.